package server

import (
	"CSCredis/db"
	"CSCredis/interface/server"
	"CSCredis/logger"
	"CSCredis/reply"
	"fmt"
	"net"
	"sync"
)

/**
 * @Author: hejing@szlabsun.com
 * @Description: 来自命令行的指令解析处理器
 * @File:  cmdHandler
 * @Version: 1.0.0
 * @Date: 2021/6/23 17:31
 */

var (
	unknownErrReplyBytes = []byte("-ERR unknown\r\n")
)

type Handler struct {
	//activeConn *sync.Map // 这个处理器处理过的 还在活跃状态下的连接
	activeConn sync.Map // 这个处理器处理过的 还在活跃状态下的连接 (加*号是指针，会导致初始化失败)
	// 数据库操作对象
	Db db.DB
}

func NewHandler() *Handler {
	return &Handler{}
}

func (h *Handler) Handle(client server.Client) {
	h.activeConn.Store(client, 1) //
	ch := ParseStream(client.GetConn())
	for result := range ch { // 从通道里循环读数据
		if err := result.Err; err != nil {
			fmt.Println("数据解析出错" + err.Error())
		}
		if result.Data == nil {
			logger.Error("empty result")
			continue
		}
		r, ok := result.Data.(*reply.MultiBulkReply)
		if !ok {
			logger.Error("require multi bulk reply")
			continue
		}
		result := h.Db.Exec(client, r.Args)
		if result != nil {
			_ = client.Write(result.ToBytes())
		} else {
			_ = client.Write(unknownErrReplyBytes)
		}
	}
}

func (h *Handler) Close() error {
	// TODO: concurrent wait
	h.activeConn.Range(func(key interface{}, val interface{}) bool {
		connection := key.(*net.Conn)
		_ = (*connection).Close()
		return true
	})
	return nil
}
